home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / minmax.cc < prev    next >
C/C++ Source or Header  |  1996-11-03  |  15KB  |  796 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include "lo-ieee.h"
  28. #include "oct-math.h"
  29.  
  30. #include "defun-dld.h"
  31. #include "error.h"
  32. #include "gripes.h"
  33. #include "help.h"
  34. #include "oct-obj.h"
  35.  
  36. #ifndef MAX
  37. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  38. #endif
  39.  
  40. #ifndef MIN
  41. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  42. #endif
  43.  
  44. // XXX FIXME XXX -- it would be nice to share code among the min/max
  45. // functions below.
  46.  
  47. static Matrix
  48. min (double d, const Matrix& m)
  49. {
  50.   int nr = m.rows ();
  51.   int nc = m.columns ();
  52.  
  53.   Matrix result (nr, nc);
  54.  
  55.   for (int j = 0; j < nc; j++)
  56.     for (int i = 0; i < nr; i++)
  57.       {
  58.     double m_elem = m (i, j);
  59.     result (i, j) = MIN (d, m_elem);
  60.       }
  61.  
  62.   return result;
  63. }
  64.  
  65. static Matrix
  66. min (const Matrix& m, double d)
  67. {
  68.   int nr = m.rows ();
  69.   int nc = m.columns ();
  70.  
  71.   Matrix result (nr, nc);
  72.  
  73.   for (int j = 0; j < nc; j++)
  74.     for (int i = 0; i < nr; i++)
  75.       {
  76.     double m_elem = m (i, j);
  77.     result (i, j) = MIN (m_elem, d);
  78.       }
  79.  
  80.   return result;
  81. }
  82.  
  83. static ComplexMatrix
  84. min (const Complex& c, const ComplexMatrix& m)
  85. {
  86.   int nr = m.rows ();
  87.   int nc = m.columns ();
  88.  
  89.   ComplexMatrix result (nr, nc);
  90.  
  91.   double abs_c = abs (c);
  92.  
  93.   for (int j = 0; j < nc; j++)
  94.     {
  95.       for (int i = 0; i < nr; i++)
  96.     {
  97.       double abs_m_elem = abs (m (i, j));
  98.       if (abs_c < abs_m_elem)
  99.         result (i, j) = c;
  100.       else
  101.         result (i, j) = m (i, j);
  102.     }
  103.     }
  104.  
  105.   return result;
  106. }
  107.  
  108. static ComplexMatrix
  109. min (const ComplexMatrix& m, const Complex& c)
  110. {
  111.   int nr = m.rows ();
  112.   int nc = m.columns ();
  113.  
  114.   ComplexMatrix result (nr, nc);
  115.  
  116.   double abs_c = abs (c);
  117.  
  118.   for (int j = 0; j < nc; j++)
  119.     for (int i = 0; i < nr; i++)
  120.       {
  121.     double abs_m_elem = abs (m (i, j));
  122.     if (abs_m_elem < abs_c)
  123.       result (i, j) = m (i, j);
  124.     else
  125.       result (i, j) = c;
  126.       }
  127.  
  128.   return result;
  129. }
  130.  
  131. static Matrix
  132. min (const Matrix& a, const Matrix& b)
  133. {
  134.   int nr = a.rows ();
  135.   int nc = a.columns ();
  136.   if (nr != b.rows () || nc != b.columns ())
  137.     {
  138.       error ("two-arg min expecting args of same size");
  139.       return Matrix ();
  140.     }
  141.  
  142.   Matrix result (nr, nc);
  143.  
  144.   for (int j = 0; j < nc; j++)
  145.     for (int i = 0; i < nr; i++)
  146.       {
  147.     double a_elem = a (i, j);
  148.     double b_elem = b (i, j);
  149.     result (i, j) = MIN (a_elem, b_elem);
  150.       }
  151.  
  152.   return result;
  153. }
  154.  
  155. static ComplexMatrix
  156. min (const ComplexMatrix& a, const ComplexMatrix& b)
  157. {
  158.   int nr = a.rows ();
  159.   int nc = a.columns ();
  160.   if (nr != b.rows () || nc != b.columns ())
  161.     {
  162.       error ("two-arg min expecting args of same size");
  163.       return ComplexMatrix ();
  164.     }
  165.  
  166.   ComplexMatrix result (nr, nc);
  167.  
  168.   for (int j = 0; j < nc; j++)
  169.     {
  170.       int columns_are_real_only = 1;
  171.       for (int i = 0; i < nr; i++)
  172.     if (imag (a (i, j)) != 0.0 && imag (b (i, j)) != 0.0)
  173.       {
  174.         columns_are_real_only = 0;
  175.         break;
  176.       }
  177.  
  178.       if (columns_are_real_only)
  179.     {
  180.       for (int i = 0; i < nr; i++)
  181.         {
  182.           double a_elem = real (a (i, j));
  183.           double b_elem = real (b (i, j));
  184.           if (a_elem < b_elem)
  185.         result (i, j) = a_elem;
  186.           else
  187.         result (i, j) = b_elem;
  188.         }
  189.     }
  190.       else
  191.     {
  192.       for (int i = 0; i < nr; i++)
  193.         {
  194.           double abs_a_elem = abs (a (i, j));
  195.           double abs_b_elem = abs (b (i, j));
  196.           if (abs_a_elem < abs_b_elem)
  197.         result (i, j) = a (i, j);
  198.           else
  199.         result (i, j) = b (i, j);
  200.         }
  201.     }
  202.     }
  203.  
  204.   return result;
  205. }
  206.  
  207. static Matrix
  208. max (double d, const Matrix& m)
  209. {
  210.   int nr = m.rows ();
  211.   int nc = m.columns ();
  212.  
  213.   Matrix result (nr, nc);
  214.  
  215.   for (int j = 0; j < nc; j++)
  216.     for (int i = 0; i < nr; i++)
  217.       {
  218.     double m_elem = m (i, j);
  219.     result (i, j) = MAX (d, m_elem);
  220.       }
  221.  
  222.   return result;
  223. }
  224.  
  225. static Matrix
  226. max (const Matrix& m, double d)
  227. {
  228.   int nr = m.rows ();
  229.   int nc = m.columns ();
  230.  
  231.   Matrix result (nr, nc);
  232.  
  233.   for (int j = 0; j < nc; j++)
  234.     for (int i = 0; i < nr; i++)
  235.       {
  236.     double m_elem = m (i, j);
  237.     result (i, j) = MAX (m_elem, d);
  238.       }
  239.  
  240.   return result;
  241. }
  242.  
  243. static ComplexMatrix
  244. max (const Complex& c, const ComplexMatrix& m)
  245. {
  246.   int nr = m.rows ();
  247.   int nc = m.columns ();
  248.  
  249.   ComplexMatrix result (nr, nc);
  250.  
  251.   double abs_c = abs (c);
  252.  
  253.   for (int j = 0; j < nc; j++)
  254.     for (int i = 0; i < nr; i++)
  255.       {
  256.     double abs_m_elem = abs (m (i, j));
  257.     if (abs_c > abs_m_elem)
  258.       result (i, j) = c;
  259.     else
  260.       result (i, j) = m (i, j);
  261.       }
  262.  
  263.   return result;
  264. }
  265.  
  266. static ComplexMatrix
  267. max (const ComplexMatrix& m, const Complex& c)
  268. {
  269.   int nr = m.rows ();
  270.   int nc = m.columns ();
  271.  
  272.   ComplexMatrix result (nr, nc);
  273.  
  274.   double abs_c = abs (c);
  275.  
  276.   for (int j = 0; j < nc; j++)
  277.     for (int i = 0; i < nr; i++)
  278.       {
  279.     double abs_m_elem = abs (m (i, j));
  280.     if (abs_m_elem > abs_c)
  281.       result (i, j) = m (i, j);
  282.     else
  283.       result (i, j) = c;
  284.       }
  285.  
  286.   return result;
  287. }
  288.  
  289. static Matrix
  290. max (const Matrix& a, const Matrix& b)
  291. {
  292.   int nr = a.rows ();
  293.   int nc = a.columns ();
  294.   if (nr != b.rows () || nc != b.columns ())
  295.     {
  296.       error ("two-arg max expecting args of same size");
  297.       return Matrix ();
  298.     }
  299.  
  300.   Matrix result (nr, nc);
  301.  
  302.   for (int j = 0; j < nc; j++)
  303.     for (int i = 0; i < nr; i++)
  304.       {
  305.     double a_elem = a (i, j);
  306.     double b_elem = b (i, j);
  307.     result (i, j) = MAX (a_elem, b_elem);
  308.       }
  309.  
  310.   return result;
  311. }
  312.  
  313. static ComplexMatrix
  314. max (const ComplexMatrix& a, const ComplexMatrix& b)
  315. {
  316.   int nr = a.rows ();
  317.   int nc = a.columns ();
  318.   if (nr != b.rows () || nc != b.columns ())
  319.     {
  320.       error ("two-arg max expecting args of same size");
  321.       return ComplexMatrix ();
  322.     }
  323.  
  324.   ComplexMatrix result (nr, nc);
  325.  
  326.   for (int j = 0; j < nc; j++)
  327.     {
  328.       int columns_are_real_only = 1;
  329.       for (int i = 0; i < nr; i++)
  330.     if (imag (a (i, j)) != 0.0 && imag (b (i, j)) != 0.0)
  331.       {
  332.         columns_are_real_only = 0;
  333.         break;
  334.       }
  335.  
  336.       if (columns_are_real_only)
  337.     {
  338.       for (int i = 0; i < nr; i++)
  339.         {
  340.           double a_elem = real (a (i, j));
  341.           double b_elem = real (b (i, j));
  342.           if (a_elem > b_elem)
  343.         result (i, j) = a_elem;
  344.           else
  345.         result (i, j) = b_elem;
  346.         }
  347.     }
  348.       else
  349.     {
  350.       for (int i = 0; i < nr; i++)
  351.         {
  352.           double abs_a_elem = abs (a (i, j));
  353.           double abs_b_elem = abs (b (i, j));
  354.           if (abs_a_elem > abs_b_elem)
  355.         result (i, j) = a (i, j);
  356.           else
  357.         result (i, j) = b (i, j);
  358.         }
  359.     }
  360.     }
  361.  
  362.   return result;
  363. }
  364.  
  365. DEFUN_DLD (min, args, nargout,
  366.   "min (X): minimum value(s) of a vector (matrix)")
  367. {
  368.   octave_value_list retval;
  369.  
  370.   int nargin = args.length ();
  371.  
  372.   if (nargin < 1 || nargin > 2 || nargout > 2)
  373.     {
  374.       print_usage ("min");
  375.       return retval;
  376.     }
  377.  
  378.   octave_value arg1;
  379.   octave_value arg2;
  380.  
  381.   switch (nargin)
  382.     {
  383.     case 2:
  384.       arg2 = args(1);
  385.       // Fall through...
  386.  
  387.     case 1:
  388.       arg1 = args(0);
  389.       break;
  390.  
  391.     default:
  392.       panic_impossible ();
  393.       break;
  394.     }
  395.  
  396.   if (nargin == 1 && (nargout == 1 || nargout == 0))
  397.     {
  398.       if (arg1.is_real_type ())
  399.     {
  400.       Matrix m = arg1.matrix_value ();
  401.  
  402.       if (! error_state)
  403.         {
  404.           if (m.rows () == 1)
  405.         retval(0) = m.row_min ();
  406.           else
  407.         retval(0) = octave_value (m.column_min (), 0);
  408.         }
  409.     }
  410.       else if (arg1.is_complex_type ())
  411.     {
  412.       ComplexMatrix m = arg1.complex_matrix_value ();
  413.  
  414.       if (! error_state)
  415.         {
  416.           if (m.rows () == 1)
  417.         retval(0) = m.row_min ();
  418.           else
  419.         retval(0) = octave_value (m.column_min (), 0);
  420.         }
  421.     }
  422.       else
  423.     gripe_wrong_type_arg ("min", arg1);
  424.     }
  425.   else if (nargin == 1 && nargout == 2)
  426.     {
  427.       Array<int> index;
  428.  
  429.       if (arg1.is_real_type ())
  430.     {
  431.       Matrix m = arg1.matrix_value ();
  432.  
  433.       if (! error_state)
  434.         {
  435.           retval.resize (2);
  436.  
  437.           if (m.rows () == 1)
  438.         retval(0) = m.row_min (index);
  439.           else
  440.         retval(0) = octave_value (m.column_min (index), 0);
  441.         }
  442.     }
  443.       else if (arg1.is_complex_type ())
  444.     {
  445.       ComplexMatrix m = arg1.complex_matrix_value ();
  446.  
  447.       if (! error_state)
  448.         {
  449.           retval.resize (2);
  450.  
  451.           if (m.rows () == 1)
  452.         retval(0) = m.row_min (index);
  453.           else
  454.         retval(0) = octave_value (m.column_min (index), 0);
  455.         }
  456.     }
  457.       else
  458.     gripe_wrong_type_arg ("min", arg1);
  459.  
  460.       int len = index.length ();
  461.  
  462.       if (len > 0)
  463.     {
  464.       RowVector idx (len);
  465.  
  466.       for (int i = 0; i < len; i++)
  467.         {
  468.           int tmp = index.elem (i) + 1;
  469.           idx.elem (i) = (tmp <= 0) ? octave_NaN : (double) tmp;
  470.         }
  471.  
  472.       retval(1) = octave_value (idx, 0);
  473.     }
  474.     }
  475.   else if (nargin == 2)
  476.     {
  477.       int arg1_is_scalar = arg1.is_scalar_type ();
  478.       int arg2_is_scalar = arg2.is_scalar_type ();
  479.  
  480.       int arg1_is_complex = arg1.is_complex_type ();
  481.       int arg2_is_complex = arg2.is_complex_type ();
  482.  
  483.       if (arg1_is_scalar)
  484.     {
  485.       if (arg1_is_complex || arg2_is_complex)
  486.         {
  487.           Complex c1 = arg1.complex_value ();
  488.           ComplexMatrix m2 = arg2.complex_matrix_value ();
  489.           if (! error_state)
  490.         {
  491.           ComplexMatrix result = min (c1, m2);
  492.           if (! error_state)
  493.             retval(0) = result;
  494.         }
  495.         }
  496.       else
  497.         {
  498.           double d1 = arg1.double_value ();
  499.           Matrix m2 = arg2.matrix_value ();
  500.  
  501.           if (! error_state)
  502.         {
  503.           Matrix result = min (d1, m2);
  504.           if (! error_state)
  505.             retval(0) = result;
  506.         }
  507.         }
  508.     }
  509.       else if (arg2_is_scalar)
  510.     {
  511.       if (arg1_is_complex || arg2_is_complex)
  512.         {
  513.           ComplexMatrix m1 = arg1.complex_matrix_value ();
  514.  
  515.           if (! error_state)
  516.         {
  517.           Complex c2 = arg2.complex_value ();
  518.           ComplexMatrix result = min (m1, c2);
  519.           if (! error_state)
  520.             retval(0) = result;
  521.         }
  522.         }
  523.       else
  524.         {
  525.           Matrix m1 = arg1.matrix_value ();
  526.  
  527.           if (! error_state)
  528.         {
  529.           double d2 = arg2.double_value ();
  530.           Matrix result = min (m1, d2);
  531.           if (! error_state)
  532.             retval(0) = result;
  533.         }
  534.         }
  535.     }
  536.       else
  537.     {
  538.       if (arg1_is_complex || arg2_is_complex)
  539.         {
  540.           ComplexMatrix m1 = arg1.complex_matrix_value ();
  541.  
  542.           if (! error_state)
  543.         {
  544.           ComplexMatrix m2 = arg2.complex_matrix_value ();
  545.  
  546.           if (! error_state)
  547.             {
  548.               ComplexMatrix result = min (m1, m2);
  549.               if (! error_state)
  550.             retval(0) = result;
  551.             }
  552.         }
  553.         }
  554.       else
  555.         {
  556.           Matrix m1 = arg1.matrix_value ();
  557.  
  558.           if (! error_state)
  559.         {
  560.           Matrix m2 = arg2.matrix_value ();
  561.  
  562.           if (! error_state)
  563.             {
  564.               Matrix result = min (m1, m2);
  565.               if (! error_state)
  566.             retval(0) = result;
  567.             }
  568.         }
  569.         }
  570.     }
  571.     }
  572.   else
  573.     panic_impossible ();
  574.  
  575.   return retval;
  576. }
  577.  
  578. DEFUN_DLD (max, args, nargout,
  579.   "max (X): maximum value(s) of a vector (matrix)")
  580. {
  581.   octave_value_list retval;
  582.  
  583.   int nargin = args.length ();
  584.  
  585.   if (nargin < 1 || nargin > 2 || nargout > 2)
  586.     {
  587.       print_usage ("max");
  588.       return retval;
  589.     }
  590.  
  591.   octave_value arg1;
  592.   octave_value arg2;
  593.  
  594.   switch (nargin)
  595.     {
  596.     case 2:
  597.       arg2 = args(1);
  598.       // Fall through...
  599.  
  600.     case 1:
  601.       arg1 = args(0);
  602.       break;
  603.  
  604.     default:
  605.       panic_impossible ();
  606.       break;
  607.     }
  608.  
  609.   if (nargin == 1 && (nargout == 1 || nargout == 0))
  610.     {
  611.       if (arg1.is_real_type ())
  612.     {
  613.       Matrix m = arg1.matrix_value ();
  614.  
  615.       if (! error_state)
  616.         {
  617.           if (m.rows () == 1)
  618.         retval(0) = m.row_max ();
  619.           else
  620.         retval(0) = octave_value (m.column_max (), 0);
  621.         }
  622.     }
  623.       else if (arg1.is_complex_type ())
  624.     {
  625.       ComplexMatrix m = arg1.complex_matrix_value ();
  626.  
  627.       if (! error_state)
  628.         {
  629.           if (m.rows () == 1)
  630.         retval(0) = m.row_max ();
  631.           else
  632.         retval(0) = octave_value (m.column_max (), 0);
  633.         }
  634.     }
  635.       else
  636.     gripe_wrong_type_arg ("max", arg1);
  637.     }
  638.   else if (nargin == 1 && nargout == 2)
  639.     {
  640.       Array<int> index;
  641.  
  642.       if (arg1.is_real_type ())
  643.     {
  644.       Matrix m = arg1.matrix_value ();
  645.  
  646.       if (! error_state)
  647.         {
  648.           retval.resize (2);
  649.  
  650.           if (m.rows () == 1)
  651.         retval(0) = m.row_max (index);
  652.           else
  653.         retval(0) = octave_value (m.column_max (index), 0);
  654.         }
  655.     }
  656.       else if (arg1.is_complex_type ())
  657.     {
  658.       ComplexMatrix m = arg1.complex_matrix_value ();
  659.  
  660.       if (! error_state)
  661.         {
  662.           retval.resize (2);
  663.  
  664.           if (m.rows () == 1)
  665.         retval(0) = m.row_max (index);
  666.           else
  667.         retval(0) = octave_value (m.column_max (index), 0);
  668.         }
  669.     }
  670.       else
  671.     gripe_wrong_type_arg ("max", arg1);
  672.  
  673.       int len = index.length ();
  674.  
  675.       if (len > 0)
  676.     {
  677.       RowVector idx (len);
  678.  
  679.       for (int i = 0; i < len; i++)
  680.         {
  681.           int tmp = index.elem (i) + 1;
  682.           idx.elem (i) = (tmp <= 0) ? octave_NaN : (double) tmp;
  683.         }
  684.  
  685.       retval(1) = octave_value (idx, 0);
  686.     }
  687.     }
  688.   else if (nargin == 2)
  689.     {
  690.       int arg1_is_scalar = arg1.is_scalar_type ();
  691.       int arg2_is_scalar = arg2.is_scalar_type ();
  692.  
  693.       int arg1_is_complex = arg1.is_complex_type ();
  694.       int arg2_is_complex = arg2.is_complex_type ();
  695.  
  696.       if (arg1_is_scalar)
  697.     {
  698.       if (arg1_is_complex || arg2_is_complex)
  699.         {
  700.           Complex c1 = arg1.complex_value ();
  701.           ComplexMatrix m2 = arg2.complex_matrix_value ();
  702.           if (! error_state)
  703.         {
  704.           ComplexMatrix result = max (c1, m2);
  705.           if (! error_state)
  706.             retval(0) = result;
  707.         }
  708.         }
  709.       else
  710.         {
  711.           double d1 = arg1.double_value ();
  712.           Matrix m2 = arg2.matrix_value ();
  713.  
  714.           if (! error_state)
  715.         {
  716.           Matrix result = max (d1, m2);
  717.           if (! error_state)
  718.             retval(0) = result;
  719.         }
  720.         }
  721.     }
  722.       else if (arg2_is_scalar)
  723.     {
  724.       if (arg1_is_complex || arg2_is_complex)
  725.         {
  726.           ComplexMatrix m1 = arg1.complex_matrix_value ();
  727.  
  728.           if (! error_state)
  729.         {
  730.           Complex c2 = arg2.complex_value ();
  731.           ComplexMatrix result = max (m1, c2);
  732.           if (! error_state)
  733.             retval(0) = result;
  734.         }
  735.         }
  736.       else
  737.         {
  738.           Matrix m1 = arg1.matrix_value ();
  739.  
  740.           if (! error_state)
  741.         {
  742.           double d2 = arg2.double_value ();
  743.           Matrix result = max (m1, d2);
  744.           if (! error_state)
  745.             retval(0) = result;
  746.         }
  747.         }
  748.     }
  749.       else
  750.     {
  751.       if (arg1_is_complex || arg2_is_complex)
  752.         {
  753.           ComplexMatrix m1 = arg1.complex_matrix_value ();
  754.  
  755.           if (! error_state)
  756.         {
  757.           ComplexMatrix m2 = arg2.complex_matrix_value ();
  758.  
  759.           if (! error_state)
  760.             {
  761.               ComplexMatrix result = max (m1, m2);
  762.               if (! error_state)
  763.             retval(0) = result;
  764.             }
  765.         }
  766.         }
  767.       else
  768.         {
  769.           Matrix m1 = arg1.matrix_value ();
  770.  
  771.           if (! error_state)
  772.         {
  773.           Matrix m2 = arg2.matrix_value ();
  774.  
  775.           if (! error_state)
  776.             {
  777.               Matrix result = max (m1, m2);
  778.               if (! error_state)
  779.             retval(0) = result;
  780.             }
  781.         }
  782.         }
  783.     }
  784.     }
  785.   else
  786.     panic_impossible ();
  787.  
  788.   return retval;
  789. }
  790.  
  791. /*
  792. ;;; Local Variables: ***
  793. ;;; mode: C++ ***
  794. ;;; End: ***
  795. */
  796.